Skip to content

fix(stageleft_tool): include strong-ref-enabled and target-specific deps in __deps - #89

Merged
shadaj merged 1 commit into
mainfrom
sandbox-4517617e-08a9-45d6-8f6b-97b5c2591389
Jul 29, 2026
Merged

fix(stageleft_tool): include strong-ref-enabled and target-specific deps in __deps#89
shadaj merged 1 commit into
mainfrom
sandbox-4517617e-08a9-45d6-8f6b-97b5c2591389

Conversation

@shadaj

@shadaj shadaj commented Jul 8, 2026

Copy link
Copy Markdown
Member

Completes the fix for #62. PR #65 made optional
dependencies show up in __deps behind #[cfg(any(feature = ...))]
gates, but three gaps remained (the first two are hit by real manifests
such as hydro_lang's):

  1. Strong pkg/feature references were not treated as enabling an
    optional dependency. Cargo's feat = ["tokio-stream/sync"] enables
    the optional dep tokio-stream, but optional_dep_features only
    matched dep:<name> refs, so the re-export was cfg'd out when the
    dep was enabled solely via a strong ref. The old
    dep:<name>/... prefix check was dead code (not valid Cargo syntax)
    and has been removed. Weak pkg?/feature refs correctly do not
    count as gating. The implicit feature is now appended only when no
    dep:<name> reference exists anywhere (matching Cargo semantics).

  2. [target.'cfg(...)'.dependencies] tables were ignored entirely, so
    target-specific deps (e.g. hydro_lang's linux-only procfs) never
    appeared in __deps. They are now collected and gated on the
    target's cfg predicate, composed with feature gates for optional
    deps: #[cfg(all(<target cfg>, any(feature = ...)))]. A dep
    declared in multiple tables is re-exported once, gated by any()
    of its per-declaration predicates, or ungated if any declaration is
    unconditional. Non-cfg(...) target keys (plain target triples)
    are skipped with a cargo::warning since they cannot be expressed
    as a cfg gate.

  3. A missing [dependencies] table no longer panics.

Implementation: gen_deps_module now builds a list of Dep entries
(name, package alias, Vec<DepDeclaration>) collected from the main
and target dependency tables via collect_deps_from_table, and
cfg_attr_for_declarations derives the combined #[cfg(...)]
attribute used for both the pub use re-exports and the runtime
add_deps_reexport registrations.

Tests:

  • 7 new unit tests in stageleft_tool covering strong refs, weak refs,
    target-specific deps (plain and optional), deps declared in both the
    main and target tables, deps in multiple target tables, and a
    manifest with no [dependencies] table.
  • stageleft_test_no_entry now declares my_strong_ref_feature
    (strong once_cell/std ref), my_weak_ref_feature (weak
    once_cell?/std ref), and a [target.'cfg(unix)'.dependencies]
    libc dep; the codegen snapshot shows the new gating, e.g.
    #[cfg(any(feature = "my_strong_ref_feature", feature = "once_cell"))]
    and #[cfg(unix)] pub use libc;.

Note: the snapshot must be regenerated with a full workspace build
(cargo test --workspace --all-targets, as CI does) — building the
crate alone changes prettyplease's output formatting due to feature
unification of syn's full feature.

Verified with cargo test --workspace --all-targets (61 tests pass),
cargo fmt --all -- --check, and
cargo clippy --all-targets -- -D warnings.

shadaj added a commit that referenced this pull request Jul 14, 2026
…eps in `__deps`

Completes the fix for #62. PR #65 made optional
dependencies show up in `__deps` behind `#[cfg(any(feature = ...))]`
gates, but three gaps remained (the first two are hit by real manifests
such as hydro_lang's):

1. Strong `pkg/feature` references were not treated as enabling an
   optional dependency. Cargo's `feat = ["tokio-stream/sync"]` enables
   the optional dep `tokio-stream`, but `optional_dep_features` only
   matched `dep:<name>` refs, so the re-export was cfg'd out when the
   dep was enabled solely via a strong ref. The old
   `dep:<name>/...` prefix check was dead code (not valid Cargo syntax)
   and has been removed. Weak `pkg?/feature` refs correctly do not
   count as gating. The implicit feature is now appended only when no
   `dep:<name>` reference exists anywhere (matching Cargo semantics).

2. `[target.'cfg(...)'.dependencies]` tables were ignored entirely, so
   target-specific deps (e.g. hydro_lang's linux-only `procfs`) never
   appeared in `__deps`. They are now collected and gated on the
   target's cfg predicate, composed with feature gates for optional
   deps: `#[cfg(all(<target cfg>, any(feature = ...)))]`. A dep
   declared in multiple tables is re-exported once, gated by `any()`
   of its per-declaration predicates, or ungated if any declaration is
   unconditional. Non-`cfg(...)` target keys (plain target triples)
   are skipped with a `cargo::warning` since they cannot be expressed
   as a cfg gate.

3. A missing `[dependencies]` table no longer panics.

Implementation: `gen_deps_module` now builds a list of `Dep` entries
(name, package alias, `Vec<DepDeclaration>`) collected from the main
and target dependency tables via `collect_deps_from_table`, and
`cfg_attr_for_declarations` derives the combined `#[cfg(...)]`
attribute used for both the `pub use` re-exports and the runtime
`add_deps_reexport` registrations.

Tests:
- 7 new unit tests in stageleft_tool covering strong refs, weak refs,
  target-specific deps (plain and optional), deps declared in both the
  main and target tables, deps in multiple target tables, and a
  manifest with no `[dependencies]` table.
- stageleft_test_no_entry now declares `my_strong_ref_feature`
  (strong `once_cell/std` ref), `my_weak_ref_feature` (weak
  `once_cell?/std` ref), and a `[target.'cfg(unix)'.dependencies]`
  libc dep; the codegen snapshot shows the new gating, e.g.
  `#[cfg(any(feature = "my_strong_ref_feature", feature = "once_cell"))]`
  and `#[cfg(unix)] pub use libc;`.

Note: the snapshot must be regenerated with a full workspace build
(`cargo test --workspace --all-targets`, as CI does) — building the
crate alone changes prettyplease's output formatting due to feature
unification of syn's `full` feature.

Verified with `cargo test --workspace --all-targets` (61 tests pass),
`cargo fmt --all -- --check`, and
`cargo clippy --all-targets -- -D warnings`.

Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #89
@shadaj
shadaj force-pushed the sandbox-4517617e-08a9-45d6-8f6b-97b5c2591389 branch from 5786583 to b4711fe Compare July 14, 2026 22:33
…eps in `__deps`

Completes the fix for #62. PR #65 made optional
dependencies show up in `__deps` behind `#[cfg(any(feature = ...))]`
gates, but three gaps remained (the first two are hit by real manifests
such as hydro_lang's):

1. Strong `pkg/feature` references were not treated as enabling an
   optional dependency. Cargo's `feat = ["tokio-stream/sync"]` enables
   the optional dep `tokio-stream`, but `optional_dep_features` only
   matched `dep:<name>` refs, so the re-export was cfg'd out when the
   dep was enabled solely via a strong ref. The old
   `dep:<name>/...` prefix check was dead code (not valid Cargo syntax)
   and has been removed. Weak `pkg?/feature` refs correctly do not
   count as gating. The implicit feature is now appended only when no
   `dep:<name>` reference exists anywhere (matching Cargo semantics).

2. `[target.'cfg(...)'.dependencies]` tables were ignored entirely, so
   target-specific deps (e.g. hydro_lang's linux-only `procfs`) never
   appeared in `__deps`. They are now collected and gated on the
   target's cfg predicate, composed with feature gates for optional
   deps: `#[cfg(all(<target cfg>, any(feature = ...)))]`. A dep
   declared in multiple tables is re-exported once, gated by `any()`
   of its per-declaration predicates, or ungated if any declaration is
   unconditional. Non-`cfg(...)` target keys (plain target triples)
   are skipped with a `cargo::warning` since they cannot be expressed
   as a cfg gate.

3. A missing `[dependencies]` table no longer panics.

Implementation: `gen_deps_module` now builds a list of `Dep` entries
(name, package alias, `Vec<DepDeclaration>`) collected from the main
and target dependency tables via `collect_deps_from_table`, and
`cfg_attr_for_declarations` derives the combined `#[cfg(...)]`
attribute used for both the `pub use` re-exports and the runtime
`add_deps_reexport` registrations.

Tests:
- 7 new unit tests in stageleft_tool covering strong refs, weak refs,
  target-specific deps (plain and optional), deps declared in both the
  main and target tables, deps in multiple target tables, and a
  manifest with no `[dependencies]` table.
- stageleft_test_no_entry now declares `my_strong_ref_feature`
  (strong `once_cell/std` ref), `my_weak_ref_feature` (weak
  `once_cell?/std` ref), and a `[target.'cfg(unix)'.dependencies]`
  libc dep; the codegen snapshot shows the new gating, e.g.
  `#[cfg(any(feature = "my_strong_ref_feature", feature = "once_cell"))]`
  and `#[cfg(unix)] pub use libc;`.

Note: the snapshot must be regenerated with a full workspace build
(`cargo test --workspace --all-targets`, as CI does) — building the
crate alone changes prettyplease's output formatting due to feature
unification of syn's `full` feature.

Verified with `cargo test --workspace --all-targets` (61 tests pass),
`cargo fmt --all -- --check`, and
`cargo clippy --all-targets -- -D warnings`.

Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #89
@shadaj
shadaj force-pushed the sandbox-4517617e-08a9-45d6-8f6b-97b5c2591389 branch from b4711fe to 4a38951 Compare July 14, 2026 22:33
@shadaj
shadaj marked this pull request as ready for review July 21, 2026 16:58
@shadaj
shadaj requested a review from MingweiSamuel July 21, 2026 16:58

@MingweiSamuel MingweiSamuel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@shadaj
shadaj merged commit 50d1031 into main Jul 29, 2026
6 checks passed
@shadaj
shadaj deleted the sandbox-4517617e-08a9-45d6-8f6b-97b5c2591389 branch July 29, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants